package service

import (
	"context"
	"fx_swift_boss/api"
	"fx_swift_boss/pkg/code"
	"fx_swift_boss/pkg/global"
	"fx_swift_boss/pkg/internalerrors"
	"fx_swift_boss/pkg/page"
	"github.com/spf13/cast"
)

// 汇款/收款/换汇
type ITransferSrv interface {
	// 收款记录
	TradeReceiptList(ctx context.Context, req *api.TradeReceiptListReq) (*page.Collection[*api.TradeReceiptInfoRes], error)
	// 国际汇款记录
	InternationTransferList(ctx context.Context, req *api.ITListReq) (*page.Collection[*api.ITListRes], error)
	// 国内汇款记录
	DomesticTransferList(ctx context.Context, req *api.DTListReq) (*page.Collection[*api.DTListRes], error)
}
type transferSrv struct {
}

func NewTransferSrv() ITransferSrv {
	return &transferSrv{}
}

// 收款记录
func (t *transferSrv) TradeReceiptList(ctx context.Context, req *api.TradeReceiptListReq) (*page.Collection[*api.TradeReceiptInfoRes], error) {
	var (
		err        error
		total      int
		resultList []*api.TradeReceiptInfoRes
	)

	collectionDto := &page.Collection[*api.TradeReceiptInfoRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_trade_receipt itr").
		LeftJoin("fx.ifcgate_vainfo_call_back ivcb", "itr.va_account=ivcb.account_no").
		LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=itr.merchant_no").
		Fields("itr.flow_no,itr.receive_amount,itr.actual_receive_amount,itr.receive_currency,itr.sender_name,itr.sender_account," +
			"itr.created_at,itr.fee_amount,itr.fee_currency,itr.trade_status,itr.trade_message,ivcb.account_name,ivcb.account_no,imvi.mer_name_en,imvi.mer_name_cn")
	if len(req.FlowNo) > 0 {
		mod.Where("itr.flow_no like ?", "%"+req.FlowNo+"%")
	}
	if len(req.ReceiveCurrency) > 0 {
		mod.Where("itr.receive_currency=?", req.ReceiveCurrency)
	}
	if len(req.CompanyName) > 0 {
		mod.Where("imvi.mer_name_en like ? or imvi.mer_name_cn like ?", "%"+req.CompanyName+"%", "%"+req.CompanyName+"%")
	}
	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("itr.created_at >=? and itr.created_at < ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Order("itr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 国际汇款记录
func (t *transferSrv) InternationTransferList(ctx context.Context, req *api.ITListReq) (*page.Collection[*api.ITListRes], error) {
	var (
		err        error
		total      int
		resultList []*api.ITListRes
	)
	collectionDto := &page.Collection[*api.ITListRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_internation_transfer_record itr")
	mod.LeftJoin("fx.ifcgate_internation_payee iip", "itr.payee_id=iip.id")
	mod.LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=itr.merchant_no")
	mod.Fields("iip.payee_first_name,iip.payee_last_name,iip.payee_bank_account_no," +
		"itr.biz_flow,itr.arrive_amount,itr.debit_amount,itr.debit_currency,itr.arrive_currency,itr.rate," +
		"itr.fee_amt,itr.status,itr.message as resp_desc,itr.fee_currency,itr.fee_amt feeAmt,itr.purpose,iip.payee_bank_name,iip.payee_company_name," +
		"itr.created_at,itr.updated_at,imvi.mer_name_en,imvi.mer_name_cn,itr.trade_comments,itr.purpose_remark,itr.pay_type")
	if len(req.BizFlow) > 0 {
		mod.WhereLike("itr.biz_flow", "%"+req.BizFlow+"%")
	}
	if len(req.Status) > 0 {
		mod.Where("itr.status=?", req.Status)
	}

	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("itr.created_at >=? and itr.created_at < ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Order("itr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 国内汇款记录
func (t *transferSrv) DomesticTransferList(ctx context.Context, req *api.DTListReq) (*page.Collection[*api.DTListRes], error) {
	var (
		err        error
		total      int
		resultList []*api.DTListRes
	)
	NewVAInfoSrv().GetTradeCodeType(ctx)

	collectionDto := &page.Collection[*api.DTListRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_domestic_transfer_record idr")
	mod.LeftJoin("fx.ifcgate_domestic_payee idp", "idr.payee_id=idp.id")
	mod.LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=idr.merchant_no")
	mod.Fields("idp.payee_name,idp.bank_acct_no,idr.resp_desc," +
		"idr.biz_flow_no,idr.amount,idr.debit_amount,idr.debit_currency,idr.status,idr.rate,idr.fee_amount,idr.status," +
		"idr.fee_currency,idr.created_at,idr.updated_at,idr.settlement_type,imvi.mer_name_en,imvi.mer_name_cn,idp.branch_name,idr.trade_code_type")
	if len(req.BizFlowNo) > 0 {
		mod.WhereLike("idr.biz_flow_no", "%"+req.BizFlowNo+"%")
	}
	if len(req.Status) > 0 {
		mod.Where("idr.status=?", req.Status)
	}
	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("idr.created_at >=? and idr.created_at <= ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Order("idr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	for _, value := range resultList {
		if _, ok := global.TradeCodeMap[value.TradeCodeType]; ok {
			value.TradeCodeType = global.TradeCodeMap[value.TradeCodeType]
		}
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}
